projectsparkfandomcom-20200223-history
Undefined variable and it/them behaviour
it and them cannot work the way it is described in The Magical It and Them Tiles, as it would be too costly and impractical to look for the last parent rule that evaluated to an object or object set, but that explanation is good enough and simplifies the way we understand how those tiles work. This page describes how it, them, and more generally any output, work. It turns out that there is also a notion of undefined variable which is linked to the it tile, and therefore this issue is discussed in the second section of this page. it and them One way we could think about it and them is this: it and them are set to "nothing" at the beginning of a frame, and each time a WHEN side evaluates to an object or an object set, them is set to that object or object set and it is set to that object or the first object in the object set, for the group of lines that are indented under this WHEN. If another WHEN inside that group evaluates to a new object or object set, it and them change their value again for the inner group of lines indented under that other WHEN. There is one pitfall, though: going to another page after a call will be considered as going outside of the lines that were under the last WHEN {object} / {object set}, and thus only the lines inside the called page count toward modifying the value of it and them inside that particular page. Let's look at an example: Page 1: 1 WHEN {objectA} DO test1equalsit 2 > WHEN nothing DO test2equalsit 3 > WHEN {objectB} DO test3equalsit 4 > > WHEN DO page2 5 > WHEN DO test6equalsit Page 2: 1 WHEN {objectC}equal tonothing DO test4equalsit 2 WHEN {objectD} DO test5equalsit Color code for the value of it in the kode: * Black - not set or kode doesn't run * Red - objectA * Blue - objectB * Orange - objectC * Olive - objectD As you can see, even though "call page" is colored in blue, the kode which runs during the call page is not colored in blue, it has not been set to anything. You can also point out that {objectC} equal to nothing evaluates to a boolean, not an object, and therefore it is not set to objectC; this can be useful if you want to keep the previous value of it when testing objects or object sets, but be very careful so that you remember to write WHEN {objectC} when you want to run the kode only if {objectC} does not equal to nothing, and at the same time need the value of it to be changed to objectC. For those who are interested in how it works under the hood, normally the kode should be stored as a tree, with each line of Kode being a node, and if a line B is indented under another line A, then B is the child of A, and each following child of A goes to the right of the previous child of A. Representation of the example above using trees The way the kode runs then is simple: it reads through the whole tree (from top to bottom, left to right) and skips a node if its WHEN condition is not satisfied; otherwise, it sets the corresponding outputs which will be valid for all descendants unless it is overwritten later because of a descendant new WHEN output. But what does that mean exactly, and what is a tree anyway? It is a data structure, you may have heard about different data structures like lists and arrays already. But this time, it is not a "linear" way of storing information. Instead, it starts at a root node and then branches out into more nodes. Each node has one parent (except for the root), and can have one or several children (if it doesn't, it is called a leaf). That's why we use the terminology "parent line/rule" and "child line/rule" in Project Spark. You can get more information on trees on Wikipedia, or anywhere else on the internet as it is actually a very important and well-documented data structure. Knowing what we have seen with the behaviour of call page above, we can understand what happens thanks to the trees now: each page has its own tree, and when the page tile is executed, it jumps to a new tree. This explains why we observe that the values of outputs in the other page don't apply to the new called page. One last comment about it/them and outputs in general: a consequence of the way they are set is that an output refers to the last parent rule setting this particular type of output, or the default value* in case there is no parent rule changing the output's value (*actually, as you are going to see afterwards, this is not exactly true). That's why the description of it/them in The Magical It and Them Tiles is what it is. Undefined variable So, now that you know exactly how it and them work, you should be able to tell very easily what the value of the "test" object variable is in the following kodes: 1st kode: WHEN object DO testequalsit WHEN DO displaytest 2nd kode: Page 1: WHEN object DO page2 WHEN DO displaytest Page 2: WHEN DO testequalsit 3rd kode: Page 1: WHEN object DO testequalsit > WHEN DO page2 WHEN DO displaytest Page 2: WHEN DO testequalsit However, you probably got the first two right, but not the third one. Test it in Project Spark to see the result. In that third kode, we see that "test" should be set to "it" the first time, but not the second time, because if you followed carefully the previous explanations, it is normally equal to nothing, and therefore "test" should be set to nothing, which we see is not the case. And in fact, I can reveal that the second kode didn't work "as expected" either, as "test equals it" did not work either, but since object was nothing in the first place, we did not see there was a problem. So, what happened? The answer is: undefined variable. You see, every custom variable you use has a value, even if it is undeclared, this is what is explained in the Variables. This might not be the right terminology, but I'll consider a custom variable is always defined, even if it is not declared, in the sense that it has a value and would not cause an "undefined variable" kind of error if Kode was a conventional programming language. However, outputs are not always defined. I haven't looked at all of them, but it seems that most of them are defined even if they have not been set... except for it. What does that even mean? A custom variable which is not declared is not stored anywhere in the memory, but it is defined because Kode replaces the variable tile with the default value corresponding to its type. So when Kode tries to read the it tile in this case, the fact that it is undefined means that no value is returned (instead of the default nothing): the kode is simply ignored, and because the game cannot stop and there is no debugger, you are not warned about this. In the examples 2 and 3, the kode "DO test equals it" in page 2 does not run at all, because it literally has no value. I should point out that them works fine, it returns the default value "empty object set" if it has not been set. I believe only it has this issue among the outputs, which is why I think it is a bug. But there are some other situations involving undefined variables. Indeed, we can consider the expression "{nothing} variable" is also an undefined variable. Again, if that is found in a kode, the line will not be run and you would have no way to know it was ignored. You should be very careful and keep that in mind, and to be clear, I'll give two examples: 1) WHEN DO var: nearest goblinequalspicker: Goblin Bruiserobject WHEN var: nearest goblinvar: attack mode DO > WHEN DO ... > WHEN else DO > > WHEN DO ... WHEN DO display"Nearest goblin"var: nearest goblin WHEN DO display"Nearest goblin HP:"plusvar: nearest goblinhealth If there is no Goblin Bruiser in your world, the child lines of "WHEN var: nearest goblin var: attack mode" won't run, even inside the else block! Moreover, the "Nearest goblin" text displays fine (but there is no goblin icon, as the object variable is nothing), but not "Nearest goblin HP:" as that second display is ignored since "var: nearest goblin health" is undefined. 2) WHEN Apressedorvar: my petvar: cast heal DO heal If your pet variable is nothing (e.g. it has not been invoked yet), then the kode won't run, even if you press A. To fix it, you need to make sure the object variable is not nothing before looking at its local variables: WHEN Apressed DO var: healequalstrue > WHEN elsevar: my pet DO var: healequalsvar: my petvar: cast heal > > WHEN else DO varequalsfalse WHEN var: heal DO heal That's it for the undefined variable. There may be some other case where a variable is undefined, but these (the output it when it hasn't been set and the expression {nothing} variable) are the only ones I know. Source: Undefined variable and it/them behaviour. Category:Brains